using Microsoft.AspNetCore.SignalR.Client;
using MultiAgentsClient.ChatDataStructures;
using MultiAgentsClient.Manager.DataModel;
using MultiAgentsShared;
using static MultiAgentsClient.Manager.ProjectManager;

namespace MultiAgentsClient.Service.SignalRService;

public class SignalRUserSettingsService : SignalRClientServiceBase
{
    public enum ApiRequestType
    {
        SendSessionId,
        ArchiveChatRoomApiRequest,
        DeleteChatRoomApiRequest,
        RenameChatRoomApiRequest,
        FetchProjectSettingsApiRequest,
        SaveProjectSettingsApiRequest,
        AllowToolCallChangedApiRequest,
    }

    private readonly UserDataModel userDataModel;
    private readonly SystemConfigDataModel systemConfigDataModel;

    public SignalRUserSettingsService(UserDataModel userDataModel, SystemConfigDataModel systemConfigDataModel) : base("userSettingsHub")
    {
        this.userDataModel = userDataModel;
        this.systemConfigDataModel = systemConfigDataModel;

        eventBus.Subscribe<SessionStartCommand>(cmd => { Task.Run(() => SendSessionId(cmd)); });
    }

    protected override async Task OnConnectCompleted()
    {
        await SendSessionId(new SessionStartCommand(systemConfigDataModel.sessionId, userDataModel.Id));
    }

    private async Task SendSessionId(SessionStartCommand cmd)
    {
        if (cmd.SessionId == "")
        {
            return;
        }

        await SendSignalRRequest(ApiRequestType.SendSessionId.ToString(), new Dictionary<string, object>()
            {
                { "sessionId", cmd.SessionId },
                { "userId", cmd.UserId },
            });
    }

    protected override void HubMethodRegistration()
    {
        hubConnection.On<int, string?>("FetchProjectSettingsApiResponse", FetchProjectSettingsApiResponse);
        hubConnection.On("SaveProjectSettingsResponse", SaveProjectSettingsResponse);
        hubConnection.On<int, int>("ArchiveChatRoomApiResponse", ArchiveChatRoomApiResponse);
        hubConnection.On<int, int>("DeleteChatRoomApiResponse", DeleteChatRoomApiResponse);
        hubConnection.On<int, int, string>("RenameChatRoomApiResponse", RenameChatRoomApiResponse);
        hubConnection.On<bool>("AllowToolCallChangedResponse", AllowToolCallChangedResponse);
    }

    private void ArchiveChatRoomApiResponse(int chatRoomId, int projectId)
    {
        if (chatRoomId == -1 || projectId == -1)
        {
            Debug.LogError("Archive chat room failed");
            return;
        }

        eventBus.Publish(new ArchiveChatRoomResponseCommand(chatRoomId, projectId));
    }

    private void DeleteChatRoomApiResponse(int chatRoomId, int projectId)
    {
        if (chatRoomId == -1 || projectId == -1)
        {
            Debug.LogError("Delete chat room failed");
            return;
        }

        eventBus.Publish(new DeleteChatRoomResponseCommand(chatRoomId, projectId));
    }

    private void RenameChatRoomApiResponse(int projectId, int chatRoomId, string chatRoomName)
    {
        if (chatRoomId == -1 || projectId == -1)
        {
            Debug.LogError("Rename chat room failed");
            return;
        }

        eventBus.Publish(new RenameChatRoomResponseCommand(projectId, chatRoomId, chatRoomName));
    }

    private void SaveProjectSettingsResponse()
    {
        eventBus.Publish(new SaveProjectSettingsResponseCommand());
    }

    private void FetchProjectSettingsApiResponse(int prjId, string? projSettings)
    {
        var chatPrj = userDataModel.GetChatProject(prjId);
        if (chatPrj == null)
        {
            return;
        }


        if (projSettings == null)
        {
            projSettings = "";
            Debug.LogError("Should not happen.");
        }

        chatPrj.chatProjectSettings = projSettings;

        eventBus.Publish(new FetchProjectSettingsResponseCommand(prjId, chatPrj.chatProjectSettings));
    }

    private void AllowToolCallChangedResponse(bool isAllow)
    {
        eventBus.Publish(new AllowToolCallChangedResponseCommand(isAllow));
    }
}
